package model;

import java.util.ArrayList;
import javax.swing.JOptionPane;

public class Juego {
	private ArrayList<Ciudad> ciudadesDelMundo;
	private ArrayList<ObjetoRobado> comunes;
	private ArrayList<ObjetoRobado> valiosos;
	private ArrayList<ObjetoRobado> muyValiosos;
	private ArrayList<Sospechoso> sospechosos;
	private ArrayList<Ciudad> recorridoLadron;
	private Ciudad proximaCiudad;
	private Ciudad ciudadInicial;
	private int indiceDeCiudad;
	private Jefatura jefatura;
	private Caso caso;
	private Ladron ladron;
	private Jugador jugador;
	private Rango rangoActual;
	private FechaHora fechaInicial;
	private FechaHora fechaFinal;
	private int lugaresVisitadosEnCiudadDelLadron;
	
	
	public Juego(FechaHora fInicial, FechaHora fFinal, Rango unRango, ArrayList<Ciudad> ciudades, ArrayList<Sospechoso> sospechosos, ArrayList<ObjetoRobado> comunes, ArrayList<ObjetoRobado> valiosos, ArrayList<ObjetoRobado> muyValiosos ){
	//me cargo las listas en memoria y despues me olvido ( sirve para cuando hay que actualizar el juego por el rango, no tengo que volver a pedir de los XML's )	
		this.ciudadesDelMundo = ciudades;
		this.sospechosos = sospechosos;
		this.comunes = comunes;
		this.valiosos = valiosos;
		this.muyValiosos = muyValiosos;	
	//fin de la carga de datos externos
		
		this.rangoActual = unRango;
		this.fechaInicial = new FechaHora(fInicial.obtenerDia(), fInicial.obtenerHora());
		this.fechaFinal = fFinal;
		this.caso = new Caso(fInicial, fFinal);
		this.jugador = new Jugador(unRango, this.caso.obtenerHorasDelCaso());
		this.jefatura = new Jefatura(this.caso, sospechosos, comunes, valiosos, muyValiosos);
		ObjetoRobado OR = this.rangoActual.establecerObjetoRobado(this.jefatura);
		this.jugador.setCiudadInicial(OR.obtenerCiudadDondeFueRobado());
		this.ciudadInicial = OR.obtenerCiudadDondeFueRobado();
	//Se obtiene un Ladron eligiendo un Sospechoso Random...
		this.ladron = new Ladron(sospechosos.get((int)(Math.random()*sospechosos.size())).obtenerDescripcion() , OR);
		this.ladron.generarRutaDeEscape(this.ciudadesDelMundo);
		this.recorridoLadron = this.ladron.obtenerRecorrido();
		this.indiceDeCiudad = 0;
		this.proximaCiudad = this.recorridoLadron.get(this.indiceDeCiudad);
		this.lugaresVisitadosEnCiudadDelLadron = 0;
		agregarPistasSegunLadron();
	}
	  	
	public void ActualizarJuegoSegunRango(){
		this.rangoActual = this.jefatura.asignarRango(this.jugador);
		FechaHora fInicial = new FechaHora(fechaInicial.obtenerDia(), fechaInicial.obtenerHora());
		this.caso = new Caso(fInicial, fechaFinal);	
		ObjetoRobado OR = this.rangoActual.establecerObjetoRobado(this.jefatura);
		this.jugador.assignarHorasDelCaso(this.caso.obtenerHorasDelCaso());
		this.jugador.setCiudadInicial(OR.obtenerCiudadDondeFueRobado());
		//Se obtiene un Ladron eligiendo un Sospechoso Random...
		this.ladron = new Ladron(sospechosos.get((int)(Math.random()*sospechosos.size())).obtenerDescripcion() , OR);
		this.ladron.generarRutaDeEscape(this.ciudadesDelMundo);
		this.recorridoLadron = this.ladron.obtenerRecorrido();
		this.indiceDeCiudad = 0;
		this.proximaCiudad = this.recorridoLadron.get(this.indiceDeCiudad);
		this.lugaresVisitadosEnCiudadDelLadron = 0;
		agregarPistasSegunLadron();
	}
		
	public Jugador obtenerJugador(){
		return this.jugador;
	}
	
	public Jefatura obtenerJefatura(){
		return this.jefatura;
	}
	
	public Ladron obtenerLadron(){
		return this.ladron;
	}
	
	public FechaHora obtenerFecha(){
		return this.caso.obtenerFecha();
	}
	
 	public int obtenerTiempoDelCaso(){
 		return this.jugador.obtenerTiempoDelCaso();
 	}

 	public Rango obtenerRango(){
 		return this.rangoActual;
 	}
 	
	public void setDescripcionJugador(Descripcion unaDescripcion){
 		this.jugador.actualizarDescripcion(unaDescripcion);
 	}
 	
 	public ArrayList<Ciudad> obtenerRecorridoDelLadron(){
 		return this.recorridoLadron;
 	}

  	public Ciudad obtenerProximaCiudad(){
  		return this.proximaCiudad;
  	}
 	
	public void emitirOrdenParaJugador(){
		this.jugador.emitirOrdenDeArresto(this.jefatura);
		int horasTranscurridas = this.caso.obtenerFecha().obtenerHora() + 3;
		this.caso.actualizarHoraDelCaso(horasTranscurridas);
	}
	
	private boolean sigueLaRuta(){
		boolean sigue = false;
		for(int ciudad = 0; ciudad < this.recorridoLadron.size(); ciudad++){
			if( this.jugador.obtenerCiudadActual() == this.recorridoLadron.get(ciudad) ){ sigue = true; } 
		}
		return sigue;
	}
	
	public boolean ajustarIndiceDeCiudad(){
		int indice = this.indiceDeCiudad;
		for(int ciudad = 0; ciudad < this.recorridoLadron.size(); ciudad++){
			if(this.jugador.obtenerCiudadActual().obtenerNombre().equals(this.recorridoLadron.get(ciudad).obtenerNombre())){
				this.indiceDeCiudad = ciudad + 1;
			}
		}
		return (this.indiceDeCiudad != indice) ? true : false; 
	}
	
 	public void moverJugadorACiudad(Ciudad unaCiudad){	
 				int horaTranscurrida = this.jugador.viajarACiudad(unaCiudad) + this.caso.obtenerFecha().obtenerHora();
 				int diaActual = this.caso.obtenerFecha().obtenerNumeroDeDia();
 				this.caso.actualizarHoraDelCaso(horaTranscurrida);
 				if(this.caso.obtenerFecha().cambioElDia(diaActual)){this.jugador.dormir();}
 				if(ajustarIndiceDeCiudad())
					{
						
						if (this.indiceDeCiudad == this.recorridoLadron.size()){ this.proximaCiudad = this.ladron.obtenerUltimoDestino(); }
						else { this.proximaCiudad = this.recorridoLadron.get(this.indiceDeCiudad); }
					}
 	}
 
 	public Pista moverJugadorALugar(Lugar unLugar){
 				int horaTranscurrida = this.jugador.irALugar(unLugar) + this.caso.obtenerFecha().obtenerHora();
 				this.caso.actualizarHoraDelCaso(horaTranscurrida);
 				
 				if((this.jugador.obtenerCiudadActual() == this.ladron.obtenerUltimoDestino()) && (this.jugador.obtenerLugarActual() != this.ladron.obtenerLugarActual())){
 					this.lugaresVisitadosEnCiudadDelLadron++;
					 if(this.lugaresVisitadosEnCiudadDelLadron == 1){ int horaTranscurrida2 = this.jugador.acuchillar() + this.caso.obtenerFecha().obtenerHora();
					 												  this.caso.actualizarHoraDelCaso(horaTranscurrida2);/**/JOptionPane.showMessageDialog(null,"Fuiste acuchillado.");}
					 else{
						if(this.lugaresVisitadosEnCiudadDelLadron == 2){ int horaTranscurrida2 = this.jugador.disparar() + this.caso.obtenerFecha().obtenerHora();
																		 this.caso.actualizarHoraDelCaso(horaTranscurrida2);/**/JOptionPane.showMessageDialog(null,"Recibiste un disparo.");}
					 }
 				}
 				if(!this.sigueLaRuta() && !(this.jugador.obtenerCiudadActual().obtenerNombre().equals(this.ciudadInicial.obtenerNombre()))){
 					Lugar lugarNoVisitado = new Lugar(unLugar.obtenerNombre());
 					Pista pistaVacia = new Pista("Nada sospechoso.");
 					lugarNoVisitado.setPistaFacil(pistaVacia);
 					lugarNoVisitado.setPistaMedia(pistaVacia);
 					lugarNoVisitado.setPistaDificil(pistaVacia);
 					return this.jugador.obtenerPista(lugarNoVisitado);
 				}
 				else{ if(this.jugador.obtenerCiudadActual().obtenerNombre().equals(this.ladron.obtenerUltimoDestino().obtenerNombre())){
 					Lugar lugarFinal = this.proximaCiudad.obtenerLugar(unLugar.obtenerNombre());
 					Pista pistaFinal = new Pista("Algo raro esta ocurriendo en esta ciudad.");
 					lugarFinal.setPistaFacil(pistaFinal);
 					lugarFinal.setPistaMedia(pistaFinal);
 					lugarFinal.setPistaDificil(pistaFinal);
 					}
 				};
 				
 				if(this.jugador.obtenerCiudadActual().obtenerNombre().equals(this.ciudadInicial.obtenerNombre())){
 					return this.jugador.obtenerPista(this.recorridoLadron.get(0).obtenerLugar(unLugar.obtenerNombre()));
 				}
 				
 				return this.jugador.obtenerPista(this.proximaCiudad.obtenerLugar(unLugar.obtenerNombre()));			
 	}
 	
 	public boolean verificarLadron(){
 		boolean condicion = false;
 		OrdenDeArresto orden = this.jugador.presentarOrdenDeArresto();
 		if( this.jefatura.checkearOrden(orden)){
 			boolean condicion1 = (orden.getNombre() == this.ladron.obtenerDescripcion().getNombre());
 			boolean condicion2 = (this.jugador.obtenerCiudadActual() == this.ladron.obtenerUltimoDestino());
 			boolean condicion3 = (this.jugador.obtenerLugarActual() == this.ladron.obtenerLugarActual());
 			if( condicion1 && condicion2 && condicion3){ condicion = true; this.jefatura.casoCerrado();}
 	
 		}
 		return condicion;
 	}

 	public void agregarPistasSegunLadron(){
 		String genero ="";
 		Rango novato = new Novato();
 		Rango detective = new Detective();
 		Rango sargento = new Sargento();
 		
 		genero = (this.ladron.obtenerDescripcion().getSexo().equals("masculino")) ? "hombre" : "mujer";
 	    Pista pistaF = new Pista(novato.obtenerPista(this.recorridoLadron.get(0).obtenerLugar("Banco")).obetenerDescripcion() + "\nEra "+ genero +". Tenia el cabello "+ this.ladron.obtenerDescripcion().getCabello()+"."); 
 		Pista pistaM = new Pista(detective.obtenerPista(this.recorridoLadron.get(0).obtenerLugar("Banco")).obetenerDescripcion() + "\nEra "+ genero + ". Tenia el cabello "+ this.ladron.obtenerDescripcion().getCabello()+".");
 		Pista pistaD = new Pista(sargento.obtenerPista(this.recorridoLadron.get(0).obtenerLugar("Banco")).obetenerDescripcion() + "\nEra "+ genero +". Tenia el cabello "+ this.ladron.obtenerDescripcion().getCabello()+".");
 		this.recorridoLadron.get(0).obtenerLugar("Banco").setPistaFacil(pistaF);
 		this.recorridoLadron.get(0).obtenerLugar("Banco").setPistaMedia(pistaM);
 		this.recorridoLadron.get(0).obtenerLugar("Banco").setPistaDificil(pistaD);
 	    Pista pistaF2 = new Pista(novato.obtenerPista(this.recorridoLadron.get(1).obtenerLugar("Biblioteca")).obetenerDescripcion() +"\nDijo que le gustaba " + this.ladron.obtenerDescripcion().getHobby() +"."); 
 	 	Pista pistaM2 = new Pista(detective.obtenerPista(this.recorridoLadron.get(1).obtenerLugar("Biblioteca")).obetenerDescripcion() +"\nDijo que le gustaba " + this.ladron.obtenerDescripcion().getHobby() +".");
 	 	Pista pistaD2 = new Pista(sargento.obtenerPista(this.recorridoLadron.get(1).obtenerLugar("Biblioteca")).obetenerDescripcion() +"\nDijo que le gustaba " + this.ladron.obtenerDescripcion().getHobby() +".");
 	 	this.recorridoLadron.get(1).obtenerLugar("Biblioteca").setPistaFacil(pistaF2);
 	 	this.recorridoLadron.get(1).obtenerLugar("Biblioteca").setPistaMedia(pistaM2);
 	 	this.recorridoLadron.get(1).obtenerLugar("Biblioteca").setPistaDificil(pistaD2);	
	    Pista pistaF3 = new Pista(novato.obtenerPista(this.recorridoLadron.get(2).obtenerLugar("Aeropuerto")).obetenerDescripcion() +"\nLLego en una " + this.ladron.obtenerDescripcion().getVehiculo() +"."); 
 	 	Pista pistaM3 = new Pista(detective.obtenerPista(this.recorridoLadron.get(2).obtenerLugar("Aeropuerto")).obetenerDescripcion() +"\nLLego en una " + this.ladron.obtenerDescripcion().getVehiculo() +".");
 	 	Pista pistaD3 = new Pista(sargento.obtenerPista(this.recorridoLadron.get(2).obtenerLugar("Aeropuerto")).obetenerDescripcion() +"\nLLego en una " + this.ladron.obtenerDescripcion().getVehiculo() +".");
 	 	this.recorridoLadron.get(2).obtenerLugar("Aeropuerto").setPistaFacil(pistaF3);
 	 	this.recorridoLadron.get(2).obtenerLugar("Aeropuerto").setPistaMedia(pistaM3);
 	 	this.recorridoLadron.get(2).obtenerLugar("Aeropuerto").setPistaDificil(pistaD3);
 	 	Pista pistaF4 = new Pista(novato.obtenerPista(this.recorridoLadron.get(3).obtenerLugar("Banco")).obetenerDescripcion() +"\nLLevaba " + this.ladron.obtenerDescripcion().getSenia() +"."); 
  	 	Pista pistaM4 = new Pista(detective.obtenerPista(this.recorridoLadron.get(3).obtenerLugar("Banco")).obetenerDescripcion() +"\nLLevaba " + this.ladron.obtenerDescripcion().getSenia() +".");
  	 	Pista pistaD4 = new Pista(sargento.obtenerPista(this.recorridoLadron.get(3).obtenerLugar("Banco")).obetenerDescripcion() +"\nLLevaba " + this.ladron.obtenerDescripcion().getSenia() +".");
  	 	this.recorridoLadron.get(3).obtenerLugar("Banco").setPistaFacil(pistaF4);
  	 	this.recorridoLadron.get(3).obtenerLugar("Banco").setPistaMedia(pistaM4);
  	 	this.recorridoLadron.get(3).obtenerLugar("Banco").setPistaDificil(pistaD4);
 		}
}

	


	


